package router

/*****************************
1.功能：ftp接收数据,ftp服务端
2.协议：ftp
3.作者：jackwong
4.日期：2021-06-23
******************************/
import (
	"flag"
	"io/ioutil"
	"os"
	"os/signal"
	"syscall"
	"time"

	ftpserver "github.com/fclairamb/ftpserverlib"
	"github.com/fclairamb/go-log/gokit"
	"github.com/sirupsen/logrus"

	"github.com/fclairamb/ftpserver/config"
	"github.com/fclairamb/ftpserver/server"
)

// 定义接口
type Router interface {
	CreateFtpRouter(fileName string)
}
type router struct {
}

func NewRouter() *router {
	return &router{}
}

var (
	ftpServer *ftpserver.FtpServer
	driver    *server.Server
)

func stop() {
	driver.Stop()
	if err := ftpServer.Stop(); err != nil {
		logrus.Error("Problem stopping server", "err", err)
	}
}
func signalHandler() {
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGTERM)
	for {
		sig := <-ch
		if sig == syscall.SIGTERM {
			stop()
			break
		}
	}
}

// 创建ftp网关服务端
func (vp *router) CreateFtpRouter(fileName string) {
	// Arguments vars
	var confFile string
	var onlyConf bool
	// Parsing arguments
	flag.StringVar(&confFile, "conf", "", "Configuration file")
	flag.BoolVar(&onlyConf, "conf-only", false, "Only create the conf")
	flag.Parse()
	// Setting up the logger
	logger := gokit.New().With(
		"ts", gokit.GKDefaultTimestampUTC,
		"caller", gokit.GKDefaultCaller,
	)
	autoCreate := onlyConf

	// The general idea here is that if you start it without any arg, you're probably doing a local quick&dirty run
	// possibly on a windows machine, so we're better of just using a default file name and create the file.
	if confFile == "" {
		confFile = fileName
		autoCreate = true
	}
	if autoCreate {
		if _, err := os.Stat(confFile); err != nil && os.IsNotExist(err) {
			logrus.Info("No conf file, creating one", "confFile", confFile)
			if err := ioutil.WriteFile(confFile, confFileContent(confFile), 0600); err != nil { // nolint: gomnd
				logrus.Warn("Couldn't create conf file", "confFile", confFile)
			}
		}
	}

	conf, errConfig := config.NewConfig(confFile, logger)
	if errConfig != nil {
		logrus.Warn("Can't load conf", "err", errConfig)
		return
	}
	// Loading the driver
	var errNewServer error
	driver, errNewServer = server.NewServer(conf, logger.With("component", "driver"))

	if errNewServer != nil {
		logrus.Error("Could not load the driver", "err", errNewServer)
		return
	}

	// Instantiating the server by passing our driver implementation
	ftpServer = ftpserver.NewFtpServer(driver)

	// Overriding the server default silent logger by a sub-logger (component: server)
	ftpServer.Logger = logger.With("component", "server")

	// Preparing the SIGTERM handling
	go signalHandler()

	// Blocking call, behaving similarly to the http.ListenAndServe
	if onlyConf {
		logrus.Warn("Only creating conf")
		return
	}

	if err := ftpServer.ListenAndServe(); err != nil {
		logrus.Error("Problem listening", "err", err)
	}

	// We wait at most 1 minutes for all clients to disconnect
	if err := driver.WaitGracefully(time.Minute); err != nil {
		logrus.Warn("Problem stopping server", "err", err)
	}
}

func confFileContent(fileName string) []byte {
	//创建byte 数组来存储文件
	logrus.Info("读取文件路径：", fileName)
	fileContext := make([]byte, 1024)
	//读取文件
	file, err := os.Open(fileName)

	defer func() {
		logrus.Info("准备关闭打开的文件")
		file.Close()
	}()
	if err != nil {
		logrus.Info("读取文件报错")
		return nil
	} else {
		len, _ := file.Read(fileContext)
		logrus.Info("读取数据内容：", string(fileContext), "长度：", len)
	}
	return fileContext
}
